﻿using System;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace PropertyExpression.ControllableQuery.Toolkit
{
    public class QueryCheckException: ApplicationException
    {
        public QueryCheckException(string message)
            : base(message)
        {
        }

        public QueryCheckException(string sqlCommandText, SqlException sqlException, string queryName)
            : base(GetMessage(sqlCommandText, sqlException, queryName), sqlException)
        {
        }

        private static string GetMessage(string sqlCommandText, SqlException sqlException, string queryName)
        {
            var lines = sqlCommandText.ToLines().ToArray();
            const string errorLineMark = "*";
            var maxNumberStringLength = lines.Length.ToString().Length + errorLineMark.Length;
            var stringBuilder = new StringBuilder();
            for (var index = 0; index < lines.Length; index++)
            {
                if (stringBuilder.Length != 0) stringBuilder.AppendLine();

                var lineNumber = index + 1;
                var indexString = lineNumber.ToString();
                string prefix;
                if (lineNumber == sqlException.LineNumber)
                {
                    prefix = errorLineMark + new string(' ', maxNumberStringLength - indexString.Length - errorLineMark.Length);
                }
                else
                {
                    prefix = new string(' ', maxNumberStringLength - indexString.Length);
                }
                stringBuilder.AppendFormat("{0}{1}:{2}", prefix, indexString, lines[index]);
            }

            return string.Format(
                @"{9} occurred
Message = '{0}'
QueryName = '{12}'
LineNumber = '{1}'
SqlCommandTextWithLineNumbers = 
{10}
SqlCommandText = 
{11}
Class = '{2}'
Number = '{3}'
State = '{4}'
ErrorCode = '{5}'
Procedure = '{6}'
Server = '{7}'
Source = '{8}'",
                sqlException.Message,
                sqlException.LineNumber,
                sqlException.Class,
                sqlException.Number,
                sqlException.State,
                sqlException.ErrorCode,
                sqlException.Procedure,
                sqlException.Server,
                sqlException.Source,
                sqlException.GetType(),
                stringBuilder,
                sqlCommandText,
                queryName
                );
        }
    }
}